//! @author Adam Emil Skoog
//! @date   2011-12-24

#ifndef KEDJA_EVENT_RECEIVER_H_
	#define KEDJA_EVENT_RECEIVER_H_
	#include <vector>
	#include <cassert>

	namespace kedja
	 {
		class Component;

		class EventReceiver
		 {
			public:
				template<class T> static T *const createEventReceiver();
				static bool destroyEventReceiver(EventReceiver *const);
				static EventReceiver *const getEventReceiver(const unsigned &);
				static const unsigned getEventReceiverCount();
				bool isRegisteredToComponent(Component *const) const;
				virtual ~EventReceiver();

			protected:
				Component *const getParent(const unsigned &) const;
				const unsigned getParentCount() const;

			private:
				// Parents.
				std::vector<Component *> parents;

				// Receivers.
				static std::vector<EventReceiver *> *eventReceivers;

				// Declare functions.
				static void initialise();
				static void deinitialise();
				void registerParent(Component *const);
				void deregisterParent(Component *const);

			friend class Component;
		 };

		/**
		 * Allocates, adds and returns an event receiver of the specific
		 * type as a child to the component. Do not attempt to delete this
		 * pointer.
		 * <br /><br />
		 *
		 * The specified class must be a child of EventReceiver, and must
		 * have a default constructor with no arguments.
		 *
		 * @return The new event receiver.
		 */
		template<class T> T *const EventReceiver::createEventReceiver()
		 {
			// There must have been an initialisation.
			assert(static_cast<bool>(eventReceivers));

			if (eventReceivers)
			 {
				// Allocate the new component.
				T *const result(new T);
				eventReceivers->push_back(result);
				return result;
			 }

			return NULL;
		 }
	 }
#endif
